/** @odoo-module **/

import { Component, useState, onMounted, onWillUnmount, useRef } from "@odoo/owl";
import { useService } from "@web/core/utils/hooks";
import { registry } from "@web/core/registry";
import { _t } from "@web/core/l10n/translation";

export class SidebarMenu extends Component {
    static template = "web_layout_enhance.SidebarMenu";
    static props = {};

    setup() {
        this.menuService = useService("menu");
        this.layoutConfig = useService("layoutConfig");
        this.actionService = useService("action");
        this.sidebarRef = useRef("sidebar");
        
        // 翻译文本
        this.searchPlaceholder = _t("Search menu...");
        this.clearSearchTitle = _t("Clear search");

        this.state = useState({
            menuTree: [],
            expandedMenus: {},
            searchQuery: "",
            isCollapsed: false,
            flyoutStack: [], // 存储多级悬浮菜单的栈
        });

        onMounted(() => {
            this.buildMenuTree();
            this._applyBodyLayout();
        });

        onWillUnmount(() => {
            document.body.classList.remove("o-sidebar-collapsed");
        });
    }

    _applyBodyLayout() {
        if (this.state.isCollapsed) {
            document.body.classList.add("o-sidebar-collapsed");
        } else {
            document.body.classList.remove("o-sidebar-collapsed");
        }
    }

    buildMenuTree() {
        const apps = this.menuService.getApps().map((app) => this.menuService.getMenuAsTree(app.id));
        const expanded = {};
        if (apps.length) {
            expanded[apps[0].id] = true;
        }
        this.state.menuTree = apps;
        this.state.expandedMenus = expanded;
        this.state.flyout = null;
    }

    getSidebarClass() {
        return {
            "o_sidebar_menu_collapsed": this.state.isCollapsed,
        };
    }

    isExpandedView() {
        return !this.state.isCollapsed;
    }

    toggleCollapse() {
        this.state.isCollapsed = !this.state.isCollapsed;
        this.state.flyout = null;
        this._applyBodyLayout();
    }

    getMenuChildren(menu) {
        return (menu && menu.childrenTree) || [];
    }

    isExpandedMenu(menuId) {
        return Boolean(this.state.expandedMenus[menuId]);
    }

    toggleMenu(menuId, ev) {
        ev.preventDefault();
        ev.stopPropagation();
        const expanded = { ...this.state.expandedMenus };
        expanded[menuId] = !expanded[menuId];
        this.state.expandedMenus = expanded;
        this.state.flyoutStack = [];
    }

    async onMenuClick(menu, ev, level = 0) {
        ev.preventDefault();
        ev.stopPropagation();

        const hasChildren = this.getMenuChildren(menu).length > 0;
        
        // 在折叠状态下
        if (this.state.isCollapsed) {
            if (hasChildren) {
                // 有子菜单，打开或扩展悬浮菜单
                this._openOrExtendFlyout(menu, ev.currentTarget, level);
            } else if (menu.actionID) {
                // 无子菜单，关闭悬浮菜单并打开页面
                this.state.flyoutStack = [];
                // 如果启用了多标签页，检查是否已有该标签页
                if (this.layoutConfig.isMultiTabEnabled()) {
                    this._activateOrOpenTab(menu.actionID);
                } else {
                    await this.menuService.selectMenu(menu);
                }
            }
            return;
        }

        // 在展开状态下，关闭任何打开的悬浮菜单
        this.state.flyoutStack = [];

        if (hasChildren) {
            this.toggleMenu(menu.id, ev);
        } else if (menu.actionID) {
            // 如果启用了多标签页，检查是否已有该标签页
            if (this.layoutConfig.isMultiTabEnabled()) {
                this._activateOrOpenTab(menu.actionID);
            } else {
                await this.menuService.selectMenu(menu);
            }
        }
    }
    
    _activateOrOpenTab(actionID) {
        // 尝试从环境中获取 WebClient 实例
        try {
            // 方法1：通过 env 访问
            const webclient = this.env.__owl__?.app?.root?.component || 
                             this.env.services?.action?.__webclient;
            
            if (webclient && webclient.tabState && webclient.tabState.tabs) {
                // 查找是否已有该 action 的标签页
                const existingTab = webclient.tabState.tabs.find(tab => {
                    if (typeof tab.action === 'number') {
                        return tab.action === actionID;
                    } else if (typeof tab.action === 'object' && tab.action.id) {
                        return tab.action.id === actionID;
                    }
                    return false;
                });
                
                if (existingTab) {
                    console.log('[SidebarMenu] Activating existing tab:', existingTab.id);
                    webclient.activateTab(existingTab.id);
                    return;
                }
            }
        } catch (e) {
            console.warn('[SidebarMenu] Could not access WebClient:', e);
        }
        
        // 如果没有找到现有标签页，正常执行 action（会创建新标签页）
        console.log('[SidebarMenu] Opening new tab for action:', actionID);
        this.actionService.doAction(actionID);
    }

    _openOrExtendFlyout(menu, target, level) {
        const sidebarEl = this.sidebarRef.el;
        if (!sidebarEl || !target) {
            console.warn('[SidebarMenu] Cannot open flyout: missing sidebar or target element');
            return;
        }
        
        const sidebarRect = sidebarEl.getBoundingClientRect();
        const targetRect = target.getBoundingClientRect();
        
        // 计算悬浮菜单的预估高度
        const itemCount = this.getMenuChildren(menu).length;
        const estimatedHeight = 40 + itemCount * 40; // header 40px + items 40px each
        
        // 计算 top 位置（相对于侧边栏）
        let top = targetRect.top - sidebarRect.top;
        
        // 检查是否会超出屏幕底部
        const viewportHeight = window.innerHeight;
        const absoluteTop = targetRect.top;
        const spaceBelow = viewportHeight - absoluteTop;
        
        if (estimatedHeight > spaceBelow && absoluteTop > estimatedHeight) {
            // 如果下方空间不足，且上方有足够空间，则向上显示
            top = Math.max(0, top - estimatedHeight + 40);
        }
        
        // 确保不超出侧边栏顶部和底部
        top = Math.max(0, top);
        const maxTop = sidebarRect.height - estimatedHeight;
        top = Math.min(top, Math.max(0, maxTop));
        
        // 计算 left 位置（级联显示）
        const left = level === 0 ? 64 : 240; // 第一级在侧边栏右侧64px，后续级在前一级右侧
        
        const flyoutData = {
            menuId: menu.id,
            label: menu.name,
            items: this.getMenuChildren(menu),
            top,
            left,
            level,
        };
        
        console.log('[SidebarMenu] Opening flyout:', menu.name, 'level:', level, 'top:', top, 'left:', left);
        
        // 如果是第一级，清空栈并添加；如果是子级，只保留到当前级
        if (level === 0) {
            this.state.flyoutStack = [flyoutData];
        } else {
            // 移除当前级及之后的所有菜单，然后添加新菜单
            this.state.flyoutStack = [...this.state.flyoutStack.slice(0, level), flyoutData];
        }
    }

    closeFlyout(ev) {
        if (ev) {
            ev.preventDefault();
            ev.stopPropagation();
        }
        this.state.flyoutStack = [];
    }
    
    onFlyoutItemHover(menu, ev, level) {
        // 鼠标悬停时，移除当前级之后的所有子菜单
        const hasChildren = this.getMenuChildren(menu).length > 0;
        if (!hasChildren) {
            // 如果没有子菜单，移除后续级别
            this.state.flyoutStack = this.state.flyoutStack.slice(0, level + 1);
        }
    }

    getFilteredMenus() {
        const query = (this.state.isCollapsed ? "" : this.state.searchQuery || "").trim().toLowerCase();
        if (!query) {
            return this.state.menuTree;
        }
        const expanded = {};

        const filterNode = (node) => {
            const children = this.getMenuChildren(node)
                .map((child) => filterNode(child))
                .filter(Boolean);
            const matched = node.name.toLowerCase().includes(query);
            if (matched || children.length) {
                if (children.length) {
                    expanded[node.id] = true;
                }
                return { ...node, childrenTree: children };
            }
            return null;
        };

        const result = [];
        for (const root of this.state.menuTree) {
            const filtered = filterNode(root);
            if (filtered) {
                result.push(filtered);
            }
        }
        this.state.expandedMenus = expanded;
        return result;
    }

    onSearchInput(ev) {
        this.state.searchQuery = ev.target.value;
    }

    clearSearch(ev) {
        ev.preventDefault();
        ev.stopPropagation();
        this.state.searchQuery = "";
    }

    getAppIcon(menu) {
        if (menu.webIconData) {
            if (menu.webIconData.startsWith("data:")) {
                return menu.webIconData;
            }
            return `data:image/png;base64,${menu.webIconData}`;
        }
        if (menu.webIcon) {
            return menu.webIcon;
        }
        return "/web/static/img/default_icon_app.png";
    }
}

registry.category("main_components").add("SidebarMenu", {
    Component: SidebarMenu,
    props: {},
});
